package com.heima.comment.service.Impl;

import com.alibaba.fastjson.JSON;
import com.heima.comment.service.CommentService;
import com.heima.common.constants.HotArticleConstants;
import com.heima.common.constants.WemediaConstants;
import com.heima.feign.article.IArtileFeignClient;
import com.heima.feign.user.IUserFeignClient;
import com.heima.feign.wemedia.WemediaFeignClient;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentSaveDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.vos.CommentVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.mess.UpdateArticleMess;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.thread.ApThreadLocalUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    private WemediaFeignClient wemediaFeignClient;
    @Autowired
    private IUserFeignClient userFeignClient;
    @Autowired
    private IArtileFeignClient articleClient;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private KafkaTemplate kafkaTemplate;

    /**
     * 保存评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {

        //检查参数
        if (dto == null || StringUtils.isBlank(dto.getContent()) || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //判断当前是否是正常登录的用户
        Integer userId = ApThreadLocalUtils.getUser().getId();
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }

        //校验是否能开启评论
        if (!cheakParam(dto.getArticleId())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //评论字数限制
        int length = dto.getContent().length();
        if (length > 140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.LENGTH_SURPASS_LIMIT);//字数超过限制
        }

        //评论内容需要做文本垃圾监测
        Map resultMap = wemediaFeignClient.scanComment(dto);
        if (resultMap.get("conclusionType") == WemediaConstants.BAIDU_SCAN_NOPASS) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NO_PASS);
        }

        //保存评论到mongdb
        //先校验用户是否存在
        ApUser user = userFeignClient.findUserById(userId);
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        ApComment apComment = ApComment.builder()
                .authorId(userId)
                .authorName(user.getName())
                .content(dto.getContent())
                .createdTime(new Date())
                .entryId(dto.getArticleId())
                .image(user.getImage())
                .likes(0)
                .reply(0)
                .type(0)
                .flag(0)
                .build();
        mongoTemplate.save(apComment);

        //发送消息给app端  评论加一
        UpdateArticleMess mess = new UpdateArticleMess();
        mess.setArticleId(dto.getArticleId());
        mess.setAdd(1);
        mess.setType(UpdateArticleMess.UpdateArticleType.COMMENT);
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC, JSON.toJSONString(mess));

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    //校验评论
    private boolean cheakParam(Long articleId) {
        boolean flag = true;
        //判断是否开启了评论
        ResponseResult articleConfig = articleClient.findArticleConfigaByArticleId(articleId);
        if (!articleConfig.getCode().equals(200) || articleConfig.getData() == null) {
            flag = false;
        }

        ApArticleConfig apArticleConfig = JSON.parseObject(JSON.toJSONString(articleConfig.getData()), ApArticleConfig.class);
        if (apArticleConfig == null || !apArticleConfig.getIsComment()) {
            flag = false;
        }

        return flag;
    }


    /**
     * 查询评论列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult loadComment(CommentDto dto) {
        //参数校验
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //查询
        int size = 10;

        if (dto.getMinDate() == null){
            dto.setMinDate(new Date());
        }

        Query query = Query.query(Criteria.where("entryId").is(dto.getArticleId())
                .and("createdTime").lt(dto.getMinDate()))
                .limit(size);
        query.with(Sort.by(Sort.Direction.DESC, "createdTime"));

        List<ApComment> list = mongoTemplate.find(query, ApComment.class); //ApComment  APP评论信息
        //封装数据
        //验证登录
        ApUser apUser = ApThreadLocalUtils.getUser();
        //游客登录，展示十条最新数据
        if (apUser == null) {
            return ResponseResult.okResult(list);
        }

        //用户登录，查询点赞过的评论
        List<String> idList = list.stream().map(x -> x.getId()).collect(Collectors.toList());
        Query query1 = Query.query(Criteria.where("commentId").in(idList).and("authorId").is(apUser.getId()));
        List<ApCommentLike> apCommentLikes
                = mongoTemplate.find(query1,ApCommentLike.class);//ApCommentLike 点赞评论信息（ID，authorId，commentId）
        if (apCommentLikes.size() == 0){
            return ResponseResult.okResult(list);
        }

        List<CommentVo> resultList = new ArrayList<>(); //CommentVo 点赞信息
        list.forEach(x -> {
            CommentVo vo = new CommentVo();
            BeanUtils.copyProperties(x, vo);
            for (ApCommentLike apCommentLike : apCommentLikes) {
                if (x.getId().equals(apCommentLike.getCommentId())) {
                    vo.setOperation((short) 0);
                    break;
                }
            }
            resultList.add(vo);
        });

        return ResponseResult.okResult(resultList);
    }

    /**
     * 点赞
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult likeComment(CommentLikeDto dto) {
        //参数校验
        if (dto == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //验证登录
        ApUser apUser = ApThreadLocalUtils.getUser();
        if (apUser == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        //点赞
        if (apComment != null && dto.getOperation() == 0){
            //更新评论点赞数量
            apComment.setLikes(apComment.getLikes() + 1);
            mongoTemplate.save(apComment);
            //保存数据
            //ApCommentLike 点赞评论信息（ID，authorId，commentId）
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setCommentId(apComment.getId());
            apCommentLike.setAuthorId(apUser.getId());
            mongoTemplate.save(apCommentLike);
        //取消点赞
        }else if (apComment != null && dto.getOperation() == 1){
            //更新评论点赞数量
            int tmp = apComment.getLikes() - 1;
            if (tmp <= 0){
                tmp = 0;
            }
            apComment.setLikes(tmp);
            mongoTemplate.save(apComment);

            //删除评论点赞
            Query query = Query.query(Criteria.where("comment").is(apComment.getId()).and("authorId").is(apUser.getId()));
            mongoTemplate.remove(query,ApCommentLike.class);
        }
        //取消点赞
        Map<String,Object> result = new HashMap<>();
        result.put("likes",apComment.getLikes());
        return ResponseResult.okResult(result);
    }
}
